package net.alteiar;

import java.awt.image.BufferedImage;
import java.util.Arrays;

import net.alteiar.transformation.TransformationFunction;

public class Array2D {

	private final int width;

	private int[] array;

	public Array2D(Array2D copy) {
		array = Arrays.copyOf(copy.array, copy.array.length);
		width = copy.width;
	}

	public Array2D(int[] array, int width) {
		this.array = array;// new int[array.length];
		// System.arraycopy(array, 0, this.array, 0, array.length);
		this.width = width;
	}

	public Array2D(int width, int height) {
		this.width = width;
		array = new int[width * height];
	}

	public Array2D(int width, int height, int value) {
		this(width, height);
		Arrays.fill(array, value);
	}

	public void setArray(int[] values) {
		if (array.length != values.length)
			throw new IndexOutOfBoundsException(
					"the array is not the same size");
		this.array = values;
	}

	public void fill(int value) {
		Arrays.fill(array, value);
	}

	public int getWidth() {
		return this.width;
	}

	public int getHeight() {
		return array.length / this.width;
	}

	public void set(int x, int y, int val) {
		array[x + y * width] = val;
	}

	public int get(int x, int y) {
		return array[x + y * width];
	}

	public int[] getArray() {
		return array;
	}

	public void replaceValues(int oldValue, int newValue) {
		for (int i = 0; i < array.length; i++) {
			if (array[i] == oldValue) {
				array[i] = newValue;
			}
		}
	}

	public void replacedValues(TransformationFunction transform) {
		getReplacedValues(array, transform);
	}

	public int[] getReplacedValues(TransformationFunction transform) {
		int[] result = new int[array.length];
		getReplacedValues(result, transform);
		return result;
	}

	public void getReplacedValues(int[] vals, TransformationFunction transform) {
		for (int i = 0; i < array.length; i++) {
			vals[i] = transform.transform(array[i]);
		}
	}

	public BufferedImage buildImage() {
		BufferedImage img = new BufferedImage(getWidth(), getHeight(),
				BufferedImage.TYPE_INT_ARGB);

		img.setRGB(0, 0, getWidth(), getHeight(), array, 0, getWidth());

		return img;
	}
}
